#pragma once
#include<iostream>
#include<queue>
#include<mutex>
#include<pthread.h>
#include<condition_variable>
#include<thread>
#include"Task.hpp"
#include"log.hpp"
//单例模式
class Threadpool
{
    private:
        std::queue<Task> qTask;
        int num;
        bool stop;
        //mutex mlock;
        pthread_mutex_t mutex;
        //condition_variable tcond;
        pthread_cond_t cond;
        static Threadpool* thp;

        // lock_guard
        Threadpool(int _num = 6):num(_num),stop(false)
        {
            pthread_mutex_init(&mutex,nullptr);
            pthread_cond_init(&cond,nullptr);
        }
        Threadpool(const Threadpool& T) = delete;
        void operator=(const Threadpool& T) = delete;
    public:
        static Threadpool* GetThreadPool()
        {
            static std::mutex mtx;
            //static pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;

            if(thp == nullptr)
            {
                //pthread_mutex_lock(&mlock);
                mtx.lock();
                if(thp == nullptr)
                {
                    
                    thp = new Threadpool();
                    //cout << "初始化完成" << endl;
                    thp->InitThreadPool2();
                    
                }
                mtx.unlock();
                //pthread_mutex_unlock(&mlock);
            }
            return thp;
        }
        bool InitThreadPool2() //bit
        {
            for(int i = 0; i < num; i++){
                pthread_t tid;
                if( pthread_create(&tid, nullptr, ThreadRoutine, this) != 0){
                    LOG(FATAL, "create thread pool error!");
                    return false;
                }
            }
            LOG(INFO, "create thread pool success!");
            return true;
        }

        // void InitThreadPool()
        // {
        //     //线程初始化
        //     //cout << "开始初始化" << endl;
        //     for(int i = 0;i < num;i ++)
        //     {
        //         thread t(ThreadRoutine,this);
        //         t.detach();
        //         //cout << "初始化第一次" << endl;
        //     }
        // }
        bool IsStop()
        {
            //判断线程池是否需要退出
            return stop;
        }
        void ThreadWait()
        {
            //线程等待
            pthread_cond_wait(&cond,&mutex);
        }
        void ThreadWakeup()
        {
            //线程唤醒
            pthread_cond_signal(&cond);
        }
        void Lock()
        {
            //mlock.lock();
            pthread_mutex_lock(&mutex);
        }
        void UnLock()
        {
            //mlock.unlock();
            pthread_mutex_unlock(&mutex);
        }
        bool IsQueueEmpty()
        {
            return qTask.size() == 0 ? true : false;
        }
        static void* ThreadRoutine(void* test)
        {
            Threadpool* tp = (Threadpool*)test;
            //必须是static函数 否则会包含一个this指针
            while(true)
            {
                Task t;
                tp->Lock();

                while(tp->IsQueueEmpty())
                {
                    tp->ThreadWait(); //进入休眠
                }
                tp->PopTask(t);
                
                tp->UnLock();

                t.ProcessOn();
            }
        }
        
        void PushTask(const Task& t)
        {
            Lock();
            
            qTask.push(t);

            UnLock();
            ThreadWakeup();
        }

        void PopTask(Task& t)
        {
            t = qTask.front();
            qTask.pop();
        }

        ~Threadpool()
        {
            pthread_mutex_destroy(&mutex);
            pthread_cond_destroy(&cond);
            //pthread_mutex_destroy(&mtx);
        }
};
Threadpool* Threadpool::thp = nullptr;